# Pour tracer le diagramme E/pH de son choix : tapper diagrammeEpH() dans la console

# Ce programme permet de tracer n'importe quel diagramme ou superposition de diagramme E/pH. (Il ne fonctionne pas lorsque la dismutation implique une modification de plusieurs portions de droites comme le diagramme du chlore mais dans ce cas un message d'erreur s'affiche)
# Il est necessaire de connaîtres les especes presentes ainsi que leur phases, les potentiels standards des couples redox les plus acides pour chaque degres d'oxydation (s'il ne sont pas connu, il faut les recalculer)
# Il faut egalement connaître le pkA ou le pKs entre les especes de meme nombre d'oxydation.
# Ainsi, il faut calculer le pH de la frontiere a partir du pKs connu et des concentrations de trace et le rentrer a la place du pKa
# Attention, la convention de frontiere entre deux especes aqueuse A1 et A2 est : [A1] + [A2] = ctrace
# Derniere remarque : il n'est pas necessaire de connaître les nombres d'oxydation des especes. Elles sont en effet demandees uniquement pour se reperer plus facilement dans ce que demande le code en input

import numpy as np
import matplotlib.pyplot as plt

def espece():
    # Programme qui retourne un 5 uplet contenant le nombre de (H,O,atomes autres que H et O, charge,phase)
    
    H=input('\n nombre de H : ')
    O=input('nombre de O : ')
    El=input('nombre d\'elements differents de H et O : ')
    q=input('charge (ex -2, 0, 1 ...) : ')
    phi=input('phase (g,l,aq ou s) pour gaz, liquide, aqueux ou solide) : ')
    
    # On verifie qu'il n'y ait pas d'erreur
    if q=='+':
        q=1
    elif q=='-':
        q=-1
    for elem in [H,O,El,q] :
        if elem=='' : 
            print('Erreur, veuillez recommencer pour cette espece')
            H,O,El,q,phi=espece()
    H,O,El,q=int(H),int(O),int(El),int(q)
    if phi not in ['g','l','aq','s']:
        print('Erreur, veuillez recommencer pour cette espece')
        H,O,El,q,phi=espece()
        
    return(H,O,El,q,phi)

def coupleredox(especeox,especered):
    # Equilibre l'equation d'un couple redox dans le sens de la reduction en conditions acides
    # Les especes en entrees doivent être au minimum de la forme [H,O,El,q] mais peuvent être de la forme [H,O,El,q,phi,pKa,...]
    # Retourne les coefficients stoechiometriques dans l'ordre : [Red,Ox,H2O,H+,e-]
    # Cette fonction marche egalement pour un couple acido/basique (ex : Cu 2+ / Cu(OH)2)
    
    Hox,Oox,Elox,qox,Hred,Ored,Elred,qred=especeox[0],especeox[1],especeox[2],especeox[3],especered[0],especered[1],especered[2],especered[3]
    
    # Cas des couples de l'eau :
    if Elox==0 or Elred==0 :
        if Oox==2 :
            coeff=np.array([2,-1,0,-4,-4])
        elif Hred==2 :
            coeff=np.array([1,-1,1,-1,-1])
    # Cas general :
    else :
        coeff=np.zeros(5) # listes des coefficient stoechiometrique de : Red, Ox, H2O, H+,  e- (dans le sens de la reduction)
        coeff[0]=1 # Fixe de maniere arbitraire mais ne pas changer car c'est important pour le calcul d'un pH a partir d'un pKs
        coeff[1]=-Elred/Elox*coeff[0] # Coefficient de l'oxydant 
        coeff[2]=-Ored*coeff[0]-Oox*coeff[1] # Coefficient de H2O
        coeff[3]=-Hred*coeff[0]-Hox*coeff[1]-2*coeff[2] # Coefficient de H+
        coeff[4]=+qred*abs(coeff[0])-qox*abs(coeff[1])+coeff[3] # Coefficient de e-
    return coeff

def coeffequation(especeox,especered) :
    # Renvoie l'equation du coefficient directeur (A) de la droite separant deux especes de n.o. different : A*pH
    # Les variables entrantes sont la liste [H,O,El,q,phi,pkA]
    demieeq=coupleredox(especeox,especered)
    coeffdir=0.06/-demieeq[4]*-demieeq[3]*-1 # Le coefficient depend seulement du coefficient stoechio de H+ et de e-
    return coeffdir

def especediagrammeEpH() :
    # Fonction renvoyant une matrice indiquant l'ensemble des especes consideres ainsi que leur pkA et les potentiels standards des couples avec les especes les plus acides, et les conventions de trace
    # Matrice[0][1][2]=[H,O,El,q,phi,pkA] : Espece correspondant au diagramme 1, au deuxieme plus grand nombre d'oxydation et 3eme dans l'ordre des basicites croissantes pour ce nombre d'oxydation
    # pkA=None pour l'espece la plus acide
    
    superposition=int(input('\n Nombre de diagrammes a superposer (1,2 ou 3) : '))
    especes=[0]*superposition # Matrice de toutes les especes
    standard=[] # Liste des potentiels standards
    Element=['0']*3 # Liste des elements pour la legende
    convaq=[] # Liste des concentrations de trace totales en especes dissoutes
    convgaz=[] # Liste des conventions de trace pour des especes gazeuses
    
    for diagram in range(superposition) :
        if diagram == 0 :
            print('\n Premier diagramme')
        else :
            print('\n Diagramme suivant')    
        Element[diagram]=input('\n Atome ou molecule principale du diagramme (pour la legende) : (ex : Eau, Fe, Cu, Mn, ...) : ')
        
        convaq+=[float(input('\n Convention de frontiere : concentration totale en especes dissoutes en mol/L (ex : 0.01) (indiquer 1 dans le cas du couple de l\'eau) : '))]
        convgaz+=[float(input('\n Convention de frontiere : pression des gaz (en bar) : '))]
        
        erreur=True
        while erreur :
            deg_ox=int(input('\n Nombre de degres d\'oxydation differents a considerer : '))
            if deg_ox<2:
                print('Erreur, il faut au moins deux degres d\'oxydation differents')
            else :
                erreur=False
        
        especes[diagram]=[0]*deg_ox
        deg_ox_ls=np.zeros(deg_ox) # Liste des degres d'oxydation simplement pour ne pas perdre l'utilisateur dans la rentree des informations
        
        print('\n Liste des degres d\'oxydation (pas d\'impact s\'ils sont faux)')
        for deg in range(deg_ox) :
            if deg==0 :
                deg_ox_ls[deg]=float(input('\n Plus petit degre d\'oxydation (ex : -0.5,0,...)  : '))
            else :
                deg_ox_ls[deg]=float(input('\n Degre d\'oxydation suivant (ex : -0.5,0,...)  : '))
        
        for deg in range(deg_ox) :
            erreur=True
            while erreur :
                print('\n Nombre d\'especes au degre d\'oxydation', deg_ox_ls[deg] ,':')
                n_espece=int(input())
                if n_espece<1 :
                    print('Erreur, au moins 1 espece pour chaque degres d\'oxydation')
                else :    
                    especes[diagram][deg]=[[0]*6]*n_espece
                    erreur=False
            
            if n_espece==1 :
                H,O,El,charge,phi=espece()
                pkA=None
                especes[diagram][deg][0]=[H,O,El,charge,phi,pkA]
                
            else :    
                for i in range(n_espece) :
                    if i==0 :
                        print('\n Espece la plus acide')
                        H,O,El,charge,phi=espece()
                        pkA=None
                        especes[diagram][deg][i]=[H,O,El,charge,phi,pkA]
                    else :
                        print('\n Espece suivante dans l\'ordre des basicites croissantes')
                        H,O,El,charge,phi=espece()

                        
                        if phi=='s' :
                            pKs=float(input('\n pKs de cette derniere espece : ')) # Calcul du pH d'une frontiere entre espece solide et aqueuse a partir du pKs
                            coeff_Ks=coupleredox(especes[diagram][deg][i-1],[H,O,El,charge,phi])
                            pH=(pKs+np.log10(convaq[-1])*(-coeff_Ks[1])+14*(coeff_Ks[2]))/(-coeff_Ks[3])
                        elif especes[diagram][deg][i-1]=='s':
                            pKs=float(input('\n pKs la precedente espece : ')) # Calcul du pH d'une frontiere entre espece solide et aqueuse a partir du pKs
                            coeff_Ks=coupleredox([H,O,El,charge,phi],especes[diagram][deg][i-1])
                            pH=(pKs+np.log10(convaq[-1])*(-coeff_Ks[1])+14*(coeff_Ks[2]))/(-coeff_Ks[3])
                        else :     
                            print('\n pkA du couple de cette derniere espece (base) et de la precedente (acide)')
                            pH=float(input())
                        especes[diagram][deg][i]=[H,O,El,charge,phi,pH]
        standard_int=[0]*(deg_ox-1)
        for deg in range(1,deg_ox) :
            print('\n \n Les potentiels standards a fournir sont ceux des couples entre les especes les plus acides de chaque nombre d\'oxydation :')    
            print('Potentiel standard (en V) entre le couple de nombre d\'oxydation', deg_ox_ls[deg],' et', deg_ox_ls[deg-1],' : ')
            standard_int[deg-1]=float(input())
        standard+=[standard_int]    
    
    return standard,especes,Element,convaq,convgaz

def diagrammeEpH() :
    # Fonction a rentrer dans la console pour faire apparaître le graphique, aucune variable d'entree ni de sortie
    
    lim_inf=float(input('Limite inferieure (en V) du graphique : '))
    lim_max=float(input('Limite superieure (en V) du graphique : '))
    
    standard,especes,Element,convaq_ls,convgaz_ls=especediagrammeEpH() # On fait rentrer tous les elements necessaires au trace du graphique a l'utilisateur
    
    TracerE,TracerpH=[],[] # Listes des portions de droites a tracer (par exemple pour le couple de l'eau : TracerpH=[[14,0],[14,0]] et TracerE=[[-0.84,0],[0.39,1.23]])
    TracerE_vert,TracerpH_vert=[],[] # Listes des portions de droites verticales pour les couples acido-basiques
    i_lim=[0]*len(especes) # Indice maximum des listes TracerE, TracerpH pour les differents diagrammes (cela permettra de tracer de couleurs differentes entre autre)
    i_lim_vert=[0]*len(especes) # Indice maximum des listes TracerE_vert, TracerpH_vert pour les differents diagrammes (cela permettra de tracer de couleurs differentes entre autre)

    
    for i in range(len(especes)) :  # On parcours les differents diagrammes
        convaq,convgaz=convaq_ls[i],convgaz_ls[i]
        E_coord=[] # Listes des coordonnees E (ex pour l'eau : E_coord=[14,0,14,0])
        pH_coord=[] # Listes des coordonnees pH (ex pour l'eau : pH_coord=[-0.84,0,0.39,1.23])
        i_deg=[0]*(len(especes[i])-1) # Indice maximum des listes TracerE, TracerpH pour les differents degres d'oxydation 
        
        for deg in range(1,len(especes[i])) : # Differentes courbes (selon les differentes paires de degre d'oxydation)
           
            # Premier point (à pH=0) :
            pH_coord+=[0]
            coeff=coupleredox(especes[i][deg][0],especes[i][deg-1][0]) # Equation redox entre les especes en haut et en bas de la courbe
            
            # Le premier points est defini a une constante pres qui va dependre de l'activite des reactifs et produits et donc de leur phase
            if especes[i][deg-1][0][-2]=='l' or especes[i][deg-1][0][-2]=='s' :
                if especes[i][deg][0][-2]=='l' or especes[i][deg][0][-2]=='s' :
                    E_coord+=[standard[i][deg-1]]
                elif especes[i][deg][0][-2]=='aq' :
                    E_coord+=[standard[i][deg-1]+0.06/-coeff[4]*-coeff[1]*np.log10(convaq)]
                else :
                    E_coord+=[standard[i][deg-1]+0.06/-coeff[4]*-coeff[1]*np.log10(convgaz)]
            elif especes[i][deg-1][0][-2]=='aq' :
                if especes[i][deg][0][-2]=='aq' :
                    E_coord+=[standard[i][deg-1]+0.06/-coeff[4]*-coeff[0]*-coeff[1]*np.log10(convgaz/2)]
                else :
                    E_coord+=[standard[i][deg-1]+0.06/-coeff[4]*(-coeff[0]*np.log10(convaq)-coeff[1]*np.log10(convgaz))]
            else : 
                    E_coord+=[standard[i][deg-1]]
                
            
            # Points intermediaires de la courbe    
            partiebasse=deg-1==0 # True si l'espece en bas de la courbe est le plus fort reducteur du diagramme, False sinon
            partiehaute=deg==len(especes[i])-1 ##True si l'espece en haut de la courbe est le plus fort oxydant du diagramme, False sinon
            
            i_bas=1 # Les indices i_bas et i_haut permettent de compter et de se reperer lorsque l'on traite un probleme avec plusieur especes pour un même nombre d'oxydation (couples acide-base)
            i_haut=1 # i_haut = 1 : Espece la plus acide se situant au dessus de la courbe, i_haut=2 : seconde espece, etc...
            while i_bas+i_haut<len(especes[i][deg-1])+len(especes[i][deg]): # Tant que l'on ne considere pas le couple redox des especes les plus basiques des deux côtes de la courbe
                if i_bas==len(especes[i][deg-1]): # Cas où il n'y a plus q'une seule espece acido-basique en bas de la courbe
                    pH_coord+=[especes[i][deg][i_haut][-1]]
                    A=coeffequation(especes[i][deg][i_haut-1],especes[i][deg-1][i_bas-1])
                    E_coord+=[E_coord[-1]-A*pH_coord[-2]+A*pH_coord[-1]] # Determinee a l'aide de la pente de la courbe (A) et des conditions de continuites
                    TracerpH+=[[pH_coord[-1],pH_coord[-2]]]
                    TracerE+=[[E_coord[-1],E_coord[-2]]]
                    
                    if partiehaute : # Trace de la verticale de la courbe a la limite max du graphe
                        TracerpH_vert+=[[pH_coord[-1],pH_coord[-1]]]
                        TracerE_vert+=[[E_coord[-1],lim_max]]
                    
                    i_haut+=1
                
                elif i_haut==len(especes[i][deg-1]): # Cas où il n'y a plus q'une seule espece acido-basique en haut de la courbe
                    pH_coord+=[especes[i][deg-1][i_bas][-1]]
                    A=coeffequation(especes[i][deg][i_haut-1],especes[i][deg-1][i_bas-1])
                    E_coord+=[E_coord[-1]-A*pH_coord[-2]+A*pH_coord[-1]] # Determinee a l'aide de la pente de la courbe (A) et des conditions de continuites
                    TracerpH+=[[pH_coord[-1],pH_coord[-2]]]
                    TracerE+=[[E_coord[-1],E_coord[-2]]]
                    
                    TracerpH_vert+=[[pH_coord[-1],pH_coord[-1]]]
                    
                    if partiebasse : # Trace de la verticale de la courbe a la limite min du graphe
                        TracerE_vert+=[[E_coord[-1],lim_inf]]
                    else :  # Trace de la verticale (les limites correspondent aux courbes qui separent les degres d'oxydation)
                        Stop=True
                        if i==0 :
                            j=0
                        else :
                            j=i_lim[i-1]+1
                        while Stop : # On cherche la valeur du potentiel de la courbe precedente pour le pH de la droite verticale
                            j+=1
                            if j==len(TracerpH)-1 :
                                print('Erreur')
                                Stop=False
                            elif TracerpH[j][0]==pH_coord[-1]:
                                TracerE_vert+=[[E_coord[-1],TracerE[j][0]]]
                                Stop=False
                    i_bas+=1
                else :
                    if especes[i][deg-1][i_bas][-1]<especes[i][deg][i_haut][-1]: # Cas ou le pkA de l'espece du bas est plus faible que celle de l'espece du haut
                        pH_coord+=[especes[i][deg-1][i_bas][-1]]
                        A=coeffequation(especes[i][deg][i_haut-1],especes[i][deg-1][i_bas-1])
                        E_coord+=[E_coord[-1]-A*pH_coord[-2]+A*pH_coord[-1]] # Determinee a l'aide de la pente de la courbe (A) et des conditions de continuites
                        TracerpH+=[[pH_coord[-1],pH_coord[-2]]]
                        TracerE+=[[E_coord[-1],E_coord[-2]]]
                        
                        TracerpH_vert+=[[pH_coord[-1],pH_coord[-1]]]
                        if partiebasse : # Trace de la verticale de la courbe a la limite min du graphe
                            TracerE_vert+=[[E_coord[-1],lim_inf]]
                        else :# Trace de la verticale (les limites correspondent aux courbes qui separent les degres d'oxydation)  
                            Stop=True
                            if i==0 :
                                j=0
                            else :
                                j=i_lim[i-1]+1
                            while Stop : # On cherche la valeur du potentiel de la courbe precedente pour le pH de la droite verticale
                                j+=1
                                if j==len(TracerpH)-1 :
                                    print('Erreur')
                                    Stop=False
                                elif TracerpH[j][0]==pH_coord[-1]:
                                    TracerE_vert+=[[E_coord[-1],TracerE[j][0]]]
                                    Stop=False
                        i_bas+=1
                    else :
                        pH_coord+=[especes[i][deg][i_haut][-1]] # Cas ou le pkA de l'espece du haut est plus faible que celle de l'espece du bas
                        A=coeffequation(especes[i][deg][i_haut-1],especes[i][deg-1][i_bas-1])
                        E_coord+=[E_coord[-1]-A*pH_coord[-2]+A*pH_coord[-1]] # Determinee a l'aide de la pente de la courbe (A) et des conditions de continuites
                        TracerpH+=[[pH_coord[-1],pH_coord[-2]]]
                        TracerE+=[[E_coord[-1],E_coord[-2]]]
                        
                        
                        if partiehaute : # Trace de la verticale de la courbe a la limite max du graphe
                            TracerpH_vert+=[[pH_coord[-1],pH_coord[-1]]]
                            TracerE_vert+=[[E_coord[-1],lim_max]]
                        
                        i_haut+=1
            
            # Dernier point (pH=14)   
            
            pH_coord+=[14]
            A=coeffequation(especes[i][deg][i_haut-1],especes[i][deg-1][i_bas-1])
            E_coord+=[E_coord[-1]-A*pH_coord[-2]+A*pH_coord[-1]] # Determinee a l'aide de la pente de la courbe (A) et des conditions de continuites
            
            TracerpH+=[[pH_coord[-1],pH_coord[-2]]]
            TracerE+=[[E_coord[-1],E_coord[-2]]]
            
            # Etude des dismutations :
            if deg>1: # Une dismutation necessite qu'au moins deux courbes aient ete tracees pour qu'elles se croisent
                if TracerE[-1][0]<TracerE[i_deg[deg-2]][0] : # Croisement des courbes a pH=14
                    A_prime=(TracerE[i_deg[deg-2]][0]-TracerE[i_deg[deg-2]][1])/(TracerpH[i_deg[deg-2]][0]-TracerpH[i_deg[deg-2]][1]) # Nouveau coefficient
                    
                    # Calcul du pH limite pour lequel l'espece en question dismute :
                    if A==A_prime : # On differencie ce cas sinon dans le prochain calcul on divise par 0
                        pH_dismute=-1 # Arbitrairement place inferieur a 0 
                    else :
                        pH_dismute=(TracerE[-1][1]+A*(-TracerpH[-1][1])-TracerE[i_deg[deg-2]][1]+A_prime*(-TracerpH[i_deg[deg-2]][1]))/(A_prime-A) 
                    
                    if pH_dismute<max(TracerpH[-1][1],TracerpH[i_deg[deg-2]][1]): # Si le pH de dismutation se trouve avant le dernier pKa considere (consequence : modification de plusieurs portions de courbes ou cas du pH_dismute=-1 cf 4 lignes au dessus)
                        if len(especes[i][deg-1])==1 and len(especes[i][deg-1])==1 and len(especes[i][deg-2])==1 : # Si il n'y a a chaque fois qu'une seule espece par degre d'oxydation (ex : diagramme avec Cu / Cu + / Cu 2+), alors il faut faire disparaître une espece
                            coeff=coupleredox(especes[i][deg][0],especes[i][deg-2][0])
                            coeff_reac1=coupleredox(especes[i][deg-1][0],especes[i][deg-2][0])
                            coeff_reac2=coupleredox(especes[i][deg][0],especes[i][deg-1][0])
                            Estandard_new=(standard[i][deg-1]*abs(coeff_reac2[-1])+standard[i][deg-2]*abs(coeff_reac1[-1])*abs(coeff_reac1[1]))/abs(coeff[-1]) # Pour reprendre l'exempe du cuivre : calcul du potentiel entre Cu2+ et Cu
                            
                            coeff=coupleredox(especes[i][deg][0],especes[i][deg-2][0])
                            # Calcul de nouveau du premier point (à pH=0)
                            if especes[i][deg-2][0][-2]=='l' or especes[i][deg-2][0][-2]=='s' :
                                if especes[i][deg][0][-2]=='l' or especes[i][deg][0][-2]=='s' :
                                    E_coord[-2]=Estandard_new
                                elif especes[i][deg][0][-2]=='aq' :
                                    E_coord[-2]=Estandard_new+0.06/-coeff[4]*-coeff[1]*np.log10(convaq)
                                else :
                                    E_coord[-2]=Estandard_new+0.06/-coeff[4]*-coeff[1]*np.log10(convgaz)
                            elif especes[i][deg-2][0][-2]=='aq' :
                                if especes[i][deg][0][-2]=='aq' :
                                    E_coord[-2]=Estandard_new+0.06/-coeff[4]*-coeff[0]*-coeff[1]*np.log10(convgaz/2)
                                else :
                                    E_coord[-2]=Estandard_new+0.06/-coeff[4]*(-coeff[0]*np.log10(convaq)-coeff[1]*np.log10(convgaz))
                            else : 
                                    E_coord[-2]=Estandard_new
                            
                            # Calcul du point a pH = 14        
                            A=coeffequation(especes[i][deg][0],especes[i][deg-2][0])
                            E_coord[-1]=E_coord[-2]-A*pH_coord[-2]+A*pH_coord[-1]
                             
                            TracerE[-1]=[E_coord[-1],E_coord[-2]]
                            TracerE[-2]=[E_coord[-1],E_coord[-2]]
                            
                        else : 
                            print("Le programme n'est pas concu pour une telle situation (dismutation qui modifie plus de deux portions de pente)")
                    else : # Le pH de dismutation se trouve avant le dernier pkA considere (modification d'une seule portion de courbe)
                        # La section de courbe qui devait s'arrêter a pH=14 s'arrête finalement a pH_dismute
                        pH_coord[-1]=pH_dismute
                        TracerpH[-1]=[pH_coord[-1],pH_coord[-2]]
                        TracerpH[i_deg[deg-2]][0]=pH_coord[-1]
                        E_new=TracerE[-1][1]+A*(pH_coord[-1]-TracerpH[-1][1])
                        E_coord[-1]=E_new
                        TracerE[-1][0]=E_new
                        TracerE[i_deg[deg-2]][0]=E_new
                        
                        # On recalcule la nouvelle valeur du potentiel a pH=14
                        pH_coord+=[14]
                        A=coeffequation(especes[i][deg][i_haut-1],especes[i][deg-2][i_bas-1])
                        E_coord+=[E_new-A*pH_coord[-2]+A*pH_coord[-1]] # Determinee a l'aide de la pente de la courbe (A) et des conditions de continuites
                        
                        TracerpH+=[[pH_coord[-1],pH_coord[-2]]]
                        TracerE+=[[E_coord[-1],E_coord[-2]]]
               
                
                if deg>2:
                    indice=i_deg[deg-3]+1
                if deg==2 :
                    if i==0:
                        indice=0
                    else :
                        indice=i_lim[i-1]+1
                if TracerE[i_deg[deg-2]+1][1]<TracerE[indice][1] : # Croisement des courbes en pH = 0
                    dismutegauche=True
                else :
                    dismutegauche=False

                if dismutegauche :
                    A=(TracerE[i_deg[deg-2]+1][0]-TracerE[i_deg[deg-2]+1][1])/(TracerpH[i_deg[deg-2]+1][0]-TracerpH[i_deg[deg-2]+1][1])
                    A_prime=(TracerE[indice][0]-TracerE[indice][1])/(TracerpH[indice][0]-TracerpH[indice][1])
                    
                    pH_dismute=(TracerE[i_deg[deg-2]+1][1]+A*(-TracerpH[i_deg[deg-2]+1][1])-TracerE[indice][1]+A_prime*(-TracerpH[indice][1]))/(A_prime-A) # Calcul du pH limite de dismutation
                    
                    if pH_dismute>min(TracerpH[indice][0],TracerpH[i_deg[deg-2]+1][0]):  # Si le pH de dismutation se trouve apres le premier pKa considere (consequence : modification de plusieurs portions de courbes)
                        print("Le programme n'est pas concu pour une telle situation (dismutation qui modifie plus de deux portions de pente)")
                    else : # Modification d'une seule portion de courbe
                    
                        # Calcul du potentiel a pH_dismute
                        E_new=TracerE[i_deg[deg-2]+1][0]+A*(pH_dismute-TracerpH[i_deg[deg-2]+1][0])
                        A=coeffequation(especes[i][deg][0],especes[i][deg-2][0])
                        pH_ini=TracerpH[i_deg[deg-2]+1][1]
                        E_newnew=E_new+A*(pH_ini-pH_dismute)
                        
                        
                        TracerE[i_deg[deg-2]+1][1]=E_new
                        TracerE[indice][1]=E_new
                        TracerpH[i_deg[deg-2]+1][1]=pH_dismute
                        TracerpH[indice][1]=pH_dismute
                        
                        TracerpH.insert(i_deg[deg-2]+1,[pH_dismute,pH_ini])
                        TracerE.insert(i_deg[deg-2]+1,[E_new,E_newnew])          
            i_deg[deg-1]=len(TracerE)-1 
            
        i_lim[i]=len(TracerE)-1
        i_lim_vert[i]=len(TracerE_vert)-1
            
    
    fig,ax=plt.subplots() # Trace des courbes :
    
    for i in range(len(TracerE)) :
            if i<=i_lim[0]:
                if i==0 :
                    Label='Diagramme de '+Element[0]
                    ax.plot(TracerpH[i],TracerE[i],color='blue',label=Label)
                else :
                    ax.plot(TracerpH[i],TracerE[i],color='blue')
            elif i<=i_lim[1] :
                if i==i_lim[0]+1 :
                    Label='Diagramme de '+Element[1]
                    ax.plot(TracerpH[i],TracerE[i],color='darkorange',label=Label)
                else :
                    ax.plot(TracerpH[i],TracerE[i],color='darkorange',)
            else :
                if i==i_lim[1]+1:
                    Label='Diagramme de '+Element[2]
                    ax.plot(TracerpH[i],TracerE[i],color='black',label=Label)
                else :
                    ax.plot(TracerpH[i],TracerE[i],color='black')
    for i in range(len(TracerE_vert)) :
            if i<=i_lim_vert[0]:                
                ax.plot(TracerpH_vert[i],TracerE_vert[i],color='blue')
            elif i<=i_lim_vert[1] :
                ax.plot(TracerpH_vert[i],TracerE_vert[i],color='darkorange')
            else :
                ax.plot(TracerpH_vert[i],TracerE_vert[i],color='black')
    ax.set_ylabel('E (en V)')
    ax.set_xlabel('pH')
    ax.set_ylim(lim_inf,lim_max)
    plt.legend()
    
    return